/*
 * Copyright (C) 2011 Amlogic Inc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
#include <math.h>

#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <malloc.h>
#include <asm/byteorder.h>
#include <linux/types.h>

#include <cutils/properties.h>
#include <cutils/efuse_bch_8.h>

#include "common.h"
#include "roots.h"
#include "efuse.h"
#include "minzip/DirUtil.h"

#define EFUSE_BYTES	8
#define EFUSE_MACLEN	17

const char *efuse_dev = "/dev/efuse";

static const char *SDCARD_AUDIO_LICENSE = "/sdcard/license.efuse";
static const char *SDCARD_AUDIO_LICENSE_OLD = "/sdcard/licence1.ef";

static const char *SDCARD_ETHERNET_MAC = "/sdcard/ethmac.efuse";
static const char *SDCARD_ETHERNET_MAC_OLD = "/sdcard/mac.ef";

static const char *SDCARD_BLUETOOTH_MAC = "/sdcard/btmac.efuse";
static const char *SDCARD_BLUETOOTH_MAC_OLD = "/sdcard/btmac.ef";

#ifdef EFUSE_LICENCE_ENABLE
#define EFUSE_MENU_MAX 3
#else
#define EFUSE_MENU_MAX 2
#endif /* EFUSE_LICENCE_ENABLE */

const char *efuse_items[EFUSE_MENU_MAX + 1] = {
#ifdef EFUSE_LICENCE_ENABLE
    "audio license", 
#endif /* EFUSE_LICENCE_ENABLE */
    "ethernet mac address",
    "bluetooth mac address", 
    NULL 
};

const int efuse_item_id[EFUSE_MENU_MAX + 1] = {
#ifdef EFUSE_LICENCE_ENABLE
    EFUSE_LICENCE, 
#endif /* EFUSE_LICENCE_ENABLE */
    EFUSE_MAC,
    EFUSE_MAC_BT,
    EFUSE_NONE 
};

extern struct selabel_handle *sehandle;

extern FILE* fopen_path(const char *path, const char *mode) ;
extern void check_and_fclose(FILE *fp, const char *name);
extern const char** prepend_title(const char* const* headers);
extern int get_menu_selection(const char* const * headers, const char* const * items, int menu_only, int initial_selection, Device* device);
extern int get_image_menu_selection(int initial_selection, Device* device);


static int
efuse_opendev()
{
    int fd = open(efuse_dev, O_RDWR);
    if (fd < 0) 
        LOGE("efuse device not found\n");
    return fd;
}

static void
efuse_closedev(int fd)
{
    close(fd);
}

static size_t efuse_read(int efuse_type, char* result_buffer, size_t buffer_size, RecoveryUI* ui)
{
    loff_t ppos;
    size_t count;
    size_t read_size = 0;
    int fd = -1;
    efuseinfo_item_t efuseinfo_item;

    memset(&efuseinfo_item, 0, sizeof(efuseinfo_item_t));
    efuseinfo_item.id = efuse_id[efuse_type];

    fd  = efuse_opendev();

    if (fd >= 0) {
        if (ioctl(fd, EFUSE_INFO_GET, &efuseinfo_item))
            goto error;
        
        ppos = efuseinfo_item.offset;
        count = efuseinfo_item.data_len;

        if (buffer_size > count) {
            printf("error, buffer size not enough");
            goto error;
        }
        lseek(fd, ppos, SEEK_SET);
        read_size = read(fd, result_buffer, count);
        if(read_size != count)
            goto error;

        efuse_closedev(fd);
    }

    return read_size;
error:
    ui->Print("read efuse data %s error\n", efuse_title[efuse_type]); 
    if(fd >= 0)
        efuse_closedev(fd);
    return -1 ;
}

static size_t efuse_write(int efuse_type, unsigned char *data, size_t buffer_size, RecoveryUI* ui)
{
    size_t count;
    int ppos;
    size_t write_size = 0;
    int fd = -1;
    efuseinfo_item_t efuseinfo_item;

    memset(&efuseinfo_item, 0, sizeof(efuseinfo_item_t));
    efuseinfo_item.id = efuse_id[efuse_type];

    fd  = efuse_opendev();

    if (fd >= 0) {
        if (ioctl(fd, EFUSE_INFO_GET, &efuseinfo_item)) {
            ui->Print("efuse ioctl error\n");
            goto error;
        }

        ppos = efuseinfo_item.offset;
        count = efuseinfo_item.data_len;

        ui->Print("efuse_write offset=%d, data_len=%d\n", ppos, count);

        if (buffer_size != count) {
            ui->Print("error, efuse data %s format is wrong\n", efuse_title[efuse_type]); 
            goto error;
        }
        if (lseek(fd, ppos, SEEK_SET) == -1)
            goto error;	
        write_size = write(fd, data, buffer_size);
        if (write_size != buffer_size) {
            ui->Print("error, efuse data %s write size wrong\n", efuse_title[efuse_type]); 
            goto error;	
        }
        efuse_closedev(fd);
    } else
    ui->Print("error,%s open file failed\n", efuse_title[efuse_type]); 

    return write_size;
    
error:
    if(fd >= 0)
       efuse_closedev(fd);
    return -1 ;
}

static int efuse_written_check(int efuse_type, RecoveryUI* ui)
{
    loff_t ppos;
    int count;
    size_t read_size = 0;
    int fd = -1, i, rc = 0;
    efuseinfo_item_t efuseinfo_item;
    char buffer[MAX_EFUSE_BYTES];

    memset(&efuseinfo_item, 0, sizeof(efuseinfo_item_t));
    efuseinfo_item.id = efuse_id[efuse_type];

    fd  = efuse_opendev();
    if (fd >= 0) {
        if (ioctl(fd, EFUSE_INFO_GET, &efuseinfo_item)) {
            ui->Print("can't get efuse info\n"); 
            goto error;
        }

        ppos = efuseinfo_item.offset;
        count = efuseinfo_item.data_len;

        if (lseek(fd, ppos, SEEK_SET) == -1)
            goto error;
        
        memset(buffer, 0, MAX_EFUSE_BYTES);
        if(count != read(fd, buffer, count))
            goto error;	

        for (i = 0; i < count; i++) {
            if (buffer[i]) {
                rc = 1;
                ui->Print("this efuse segment has been written\n");
                break;
            }
        }

        efuse_closedev(fd);
    }

    return rc;
    
error:
    if(fd >= 0)
       efuse_closedev(fd);
    return -1 ;
}

/*
static int efuse_write_version(char* version_str,  RecoveryUI* ui)
{
    int rc = -1;
    unsigned char version_data[3];
    int version = -1, mach_id = -1;

    sscanf(version_str, "\"version=%d,mach_id=0x%x\"", &version, &mach_id);
    ui->Print("version=%x, mach_id=%x \n", version, mach_id);
    
    if(version == -1 || mach_id == -1)
        return -1;
    
    memset(version_data, 0, 3);
    version_data[0] = version & 0xff;
    version_data[1] = mach_id & 0xff;
    version_data[2] = (mach_id >> 8) & 0xff;
    
    if(3 == efuse_write(EFUSE_VERSION, version_data, 3, ui))
        rc = 0;

    return rc;
}
*/

#if defined(MESON3)
/**
  *  ---efuse_read_version 
  *  @version_str: save version(M3: 3 bytes) to this pointer
  *  @ui: recovery ui
  *  return: 0->have writen before, 1->haven't write before, -1->read failed
  */
int efuse_read_version(char* version_str, RecoveryUI* ui)
{
    int rc = -1;
    char versionData[3];

    memset(versionData, 0, sizeof(versionData));
    memset(version_str, 0, 512);
	
    printf("%s:%d\n", __func__, __LINE__);
    if(3 == efuse_read(EFUSE_VERSION, versionData, 3, ui)) { 
        if(versionData[0] !=0x00) {
            rc = 0;				//have write version
            sprintf(version_str, "%02x:%02x:%02x", versionData[0],versionData[1],versionData[2]);
            printf("efuse read version success,version=%s\n", version_str);
        }
        else {
            rc = 1;				//haven't writen version
            printf("haven't write version before\n");
        }
    }	

    return rc;
}
#elif defined(MESON6) 
/**
  *  ---efuse_read_version 
  *  @version_str: save version(M6: 1 byte) to this pointer
  *  @ui: recovery ui
  *  return: 0->have writen before, 1->haven't write before, -1->read failed
  */
int efuse_read_version(char* version_str, RecoveryUI* ui)
{
    int rc = -1;
    char versionData[1] = {0};
    
    memset(version_str, 0, 512);

    printf("%s:%d\n", __func__, __LINE__);
    if(1 == efuse_read(EFUSE_VERSION, (char*)versionData, 1, ui)) {
        if(versionData[0] !=0x00) {
            rc = 0;				//have write version
            sprintf(version_str, "%02x", versionData[0]);
            printf("efuse read version success,version=%s\n", version_str); 
        }
        else {
            rc = 1;				//haven't writen version
            printf("haven't write version before\n");
        }
    }	

    return rc;
}
#endif

#if defined(MESON3) 
/**
  *  ---efuse_write_version
  *  @version_str: version(M3: 3 bytes)
  *  @ui: recovery ui pointer
  *  return: 0->write success, -1->write failed
  */
int efuse_write_version(char* version_str, RecoveryUI* ui)
{
    int i, data_size, rc = -1;
    int version = -1, mach_id[2] = {-1,-1};
    char *parg, *buf[50], buffer[100];
    unsigned char version_data[3];
    char version_read[3];

    printf("prepate to write version=%s\n", version_str);
    memset(version_data, 0, sizeof(version_data));
    memset(buffer, 0, sizeof(buffer));
    strcpy(buffer, version_str);

    if((parg = strtok(buffer, ":")) == NULL) {
        printf("get m3 version:%s failed.\n", version_str);
    }
    else {
        buf[0] = strdup(parg);
        for (i = 1; i < 100; i++) {
            if((parg = strtok(NULL, ":")) == NULL) {
                break;
            }
            else {
                buf[i] = strdup(parg);
            }
        }
    }

    data_size = i;
    printf("version[%d]={", data_size);
    for(i=0; i<data_size; i++) {
        version_data[i] = strtol(buf[i], NULL, 16);	
        if(i != data_size-1)
            printf("0x%02x,", version_data[i]);
        else
            printf("0x%02x", version_data[i]);
    }
    printf("}\n");

    version = version_data[0];
    mach_id[0] = version_data[1];
    mach_id[1] = version_data[2];
    if((version == -1) ||(mach_id[0] == -1) ||(mach_id[1] == -1)) {
        printf("m3 version wrong!: version=%d,mach_id[0]=%d,mach_id[1]=%d\n", version, mach_id[0], mach_id[1]);
        return -1;
    }	

    printf("%s:%d\n", __func__, __LINE__);
    if(3 == efuse_write(EFUSE_VERSION, version_data, 3, ui)) {
        rc = 0;
    }

    //write success,test efuse read
    if(rc == 0) {
        printf("efuse write version success,start to test efuse read version...\n");
        memset(version_read, 0, sizeof(version_read));
        if(3 == efuse_read(EFUSE_VERSION, version_read, 3, ui)) {
            if(!memcmp(version_data, version_read, 3)) {
                printf("test efuse read version success,read version=%02x:%02x:%02x\n", 
                        version_read[0], version_read[1], version_read[2]);
                rc = 0;
            }
            else {
                printf("test efuse read version success,read version=%02x:%02x:%02x,but not mach write\n", 
                        version_read[0], version_read[1], version_read[2]);
                rc = -1;
            }
        }
    }

    return rc;

}
#elif defined(MESON6)
/**
  *  ---efuse_write_version
  *  @version_str: version(M6: 1 byte)
  *  @ui: recovery ui pointer
  *  return: 0->write success, -1->write failed
  */
int efuse_write_version(char* version_str, RecoveryUI* ui)
{
    int rc = -1, version = -1;
    unsigned char version_data[1];
    char version_read[1];

    printf("prepate to write version=%s \n", version_str);
    memset(version_data, 0, sizeof(version_data));

    version_data[0] = strtol(version_str, NULL, 16);
    version = version_data[0];

    if(version == -1) {
        printf("m6 version wrong!: version=%d\n",version);
        return -1;
    }

    printf("version[1]={0x%02x}\n", version_data[0]);
    printf("%s:%d\n", __func__, __LINE__);
    if(1 == efuse_write(EFUSE_VERSION, version_data, 1, ui)) {
        rc = 0;
    }	

    //write success,test efuse read
    if(rc == 0) {
        printf("efuse write version success,start to test efuse read version...\n");
        memset(version_read, 0, sizeof(version_read));
        if(1 == efuse_read(EFUSE_VERSION, version_read, 1, ui)) {
            if(!memcmp(version_data, version_read, 1)) {
                printf("test efuse read version success,read version=%02x\n", version_read[0]);
                rc = 0;
            }
            else {
                printf("test efuse read version success,read version=%02x,but not mach write\n", version_read[0]);
                rc = -1;
            }
        }
    }

    return rc;		
}
#endif

#ifndef SDCARD_EFUSE_MAC_ENABLE
/**
  *  ---efuse_read_mac
  *  @mac_str: save mac key datas to this pointer
  *  @type: mac type
  *  @ui: recovery ui pointer
  *  return: 0->have writen before, 1->haven't write before, -1->read failed
  */
int efuse_read_mac(char *mac_str, int type, RecoveryUI* ui)
{
    int i, flag = 0, rc = -1;
    char macData[6];

    memset(macData, 0, sizeof(macData));
    memset(mac_str, 0, 512);
    
    printf("%s:%d\n", __func__, __LINE__);
    if(6 == efuse_read(EFUSE_MAC, (char*)macData, 6, ui)) {
        for(i=0; i<6; i++) {
            if(macData[i] != 0x00) {
                flag = 1;
                break;
            }
        }

        if(flag) {
            rc = 0;				//have writen mac
            sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", 
                        macData[0], macData[1], macData[2], macData[3], macData[4], macData[5]);
            printf("efuse read mac success,mac=%s\n", mac_str);
        }
        else {
            rc = 1;				//haven't write mac
            printf("haven't write mac before\n");
        }
    }

    return rc;
}

/**
  *  ---efuse_write_mac
  *  @mac_str: mac key datas
  *  @type: mac type
  *  @ui: recovery ui pointer
  *  return: 0->write success, -1->write failed
  */
int efuse_write_mac(char *mac_str, int type, RecoveryUI* ui)
{
    int i, data_size, rc = -1;
    char *parg, *buf[50], buffer[100];
    char mac_data[6], mac_read[6];

    if(efuse_written_check(type, ui)) {
        LOGE("%s written already or something error\n", efuse_title[type]);
        return -1;
    }

    printf("prepate to write mac=%s\n", mac_str);
    memset(mac_data, 0, sizeof(mac_data));
    strcpy(buffer, mac_str);
	
    if((parg = strtok(buffer, ":")) == NULL) {
        printf("get mac:%s failed.\n", mac_str);
    }
    else {
        buf[0] = strdup(parg);
        for (i = 1; i < 100; i++) {
            if((parg = strtok(NULL, ":")) == NULL) {
                break;
            }
            else {
                buf[i] = strdup(parg);
            }
        }
    }

    data_size = i;
    printf("mac[%d]={", data_size);
    for(i=0; i<data_size; i++) {
        mac_data[i] = strtol(buf[i], NULL, 16);	
        if(i != data_size-1)
            printf("0x%02x,", mac_data[i]);
        else
            printf("0x%02x", mac_data[i]);
    }
    printf("}\n");

    printf("%s:%d\n", __func__, __LINE__);  
    if(6 == efuse_write(EFUSE_MAC, (unsigned char *)mac_data, 6, ui)) {
        rc = 0;
    }
    
    //write success,test efuse read
    if(rc == 0) {
        printf("efuse write mac success,start to test efuse read mac...\n");
        memset(mac_read, 0, sizeof(mac_read));   
        if(6 == efuse_read(EFUSE_MAC, mac_read, 6, ui)) {
            if(!memcmp(mac_data, mac_read, 6)) {
                printf("test efuse read mac success,read mac=%02x:%02x:%02x:%02x:%02x:%02x\n",
                        mac_read[0], mac_read[1], mac_read[2], mac_read[3], mac_read[4], mac_read[5]);
                rc = 0;
            }
            else {
                printf("test efuse read mac success,read mac=%02x:%02x:%02x:%02x:%02x:%02x,but not mach write\n",
                        mac_read[0], mac_read[1], mac_read[2], mac_read[3], mac_read[4], mac_read[5]);
                rc = -1;
            }
        }
    }	

    return rc;
 }
#endif

/**
  *  ---efuse_read_mac_bt
  *  @mac_bt_str: save mac_bt key datas to this pointer
  *  @type: mac_bt type
  *  @ui: recovery ui pointer
  *  return: 0->have writen before, 1->haven't write before, -1->read failed
  */
int efuse_read_mac_bt(char *mac_bt_str, int type, RecoveryUI* ui)
{
    int i, flag = 0, rc = -1;
    char macbtData[6];

    memset(macbtData, 0, sizeof(macbtData));
    memset(mac_bt_str, 0, 512);
    
    printf("%s:%d\n", __func__, __LINE__);
    if(6 == efuse_read(EFUSE_MAC_BT, (char*)macbtData, 6, ui)) {
        for(i=0; i<6; i++) {
            if(macbtData[i] != 0x00) {
                flag = 1;
                break;
            }
        }

        if(flag) {
            rc = 0;				//have writen mac_bt
            sprintf(mac_bt_str, "%02x:%02x:%02x:%02x:%02x:%02x", 
                        macbtData[0], macbtData[1], macbtData[2], macbtData[3], macbtData[4], macbtData[5]);
            printf("efuse read mac_bt success,mac_bt=%s\n", mac_bt_str);
        }
        else {
            rc = 1;				//haven't write mac_bt	
            printf("haven't write mac_bt before\n");
        }
    }

    return rc;
}

/**
  *  ---efuse_write_mac_bt
  *  @mac_bt_str: mac_bt key datas
  *  @type: mac_bt type
  *  @ui: recovery ui pointer
  *  return: 0->write success, -1->write failed
  */
int efuse_write_mac_bt(char *mac_bt_str, int type, RecoveryUI* ui)
{
    int i, data_size, rc = -1;
    char *parg, *buf[50], buffer[100];
    char mac_bt_data[6], mac_bt_read[6];

    if(efuse_written_check(type, ui)) {
        LOGE("%s written already or something error\n", efuse_title[type]);
        return -1;
    }

    printf("prepate to write mac_bt=%s\n", mac_bt_str);
    memset(mac_bt_data, 0, sizeof(mac_bt_data));
    strcpy(buffer, mac_bt_str);
	
    if((parg = strtok(buffer, ":")) == NULL) {
        printf("get mac:%s failed.\n", mac_bt_str);
    }
    else {
        buf[0] = strdup(parg);
        for (i = 1; i < 100; i++) {
            if((parg = strtok(NULL, ":")) == NULL) {
                break;
            }
            else {
                buf[i] = strdup(parg);
            }
        }
    }

    data_size = i;
    printf("mac_bt[%d]={", data_size);
    for(i=0; i<data_size; i++) {
        mac_bt_data[i] = strtol(buf[i], NULL, 16);	
        if(i != data_size-1)
            printf("0x%02x,", mac_bt_data[i]);
        else
            printf("0x%02x", mac_bt_data[i]);
    }
    printf("}\n");

    printf("%s:%d\n", __func__, __LINE__);  
    if(6 == efuse_write(EFUSE_MAC_BT, (unsigned char *)mac_bt_data, 6, ui)) {
        rc = 0;
    }	 

    //write success,test efuse read
    if(rc == 0) {
        printf("efuse write mac_bt success,start to test efuse read mac_bt...\n");
        memset(mac_bt_read, 0, sizeof(mac_bt_read));   
        if(6 == efuse_read(EFUSE_MAC_BT, mac_bt_read, 6, ui)) {
            if(!memcmp(mac_bt_data, mac_bt_read, 6)) {
                printf("test efuse read mac_bt success,read mac_bt=%02x:%02x:%02x:%02x:%02x:%02x\n",
                        mac_bt_read[0], mac_bt_read[1], mac_bt_read[2], mac_bt_read[3], mac_bt_read[4], mac_bt_read[5]);
                rc = 0;
            }
            else {
                printf("test efuse read mac_bt success,read mac_bt=%02x:%02x:%02x:%02x:%02x:%02x,but not mach write\n",
                        mac_bt_read[0], mac_bt_read[1], mac_bt_read[2], mac_bt_read[3], mac_bt_read[4], mac_bt_read[5]);
                rc = -1;
            }
        }
    }	

    return rc;
}

/**
  *  ---efuse_read_mac_wifi
  *  @mac_wifi_str: save mac_wifi key datas to this pointer
  *  @type: mac_wifi type
  *  @ui: recovery ui pointer
  *  return: 0->have writen before, 1->haven't write before, -1->read failed
  */
int efuse_read_mac_wifi(char *mac_wifi_str, int type, RecoveryUI* ui)
{
    int i, flag = 0, rc = -1;
    char macwifiData[6];

    memset(macwifiData, 0, sizeof(macwifiData));
    memset(mac_wifi_str, 0, 512);
    
    printf("%s:%d\n", __func__, __LINE__);
    if(6 == efuse_read(EFUSE_MAC_WIFI, (char*)macwifiData, 6, ui)) {
        for(i=0; i<6; i++) {
            if(macwifiData[i] != 0x00) {
                flag = 1;
                break;
            }
        }

        if(flag) {
            rc = 0;				//have writen mac_wifi
            sprintf(mac_wifi_str, "%02x:%02x:%02x:%02x:%02x:%02x", 
                        macwifiData[0], macwifiData[1], macwifiData[2], macwifiData[3], macwifiData[4], macwifiData[5]);
            printf("efuse read mac_wifi success,mac_wifi=%s\n", mac_wifi_str);
        }
        else {
            rc = 1;				//haven't write mac_wifi	
            printf("haven't write mac_wifi before\n");
        }
    }

    return rc;
}

/**
  *  ---efuse_write_mac_wifi
  *  @mac_wifi_str: mac_wifi key datas
  *  @type: mac_wifi type
  *  @ui: recovery ui pointer
  *  return: 0->write success, -1->write failed
  */
int efuse_write_mac_wifi(char *mac_wifi_str, int type, RecoveryUI* ui)
{
    int i, data_size, rc = -1;
    char *parg, *buf[50], buffer[100];
    char mac_wifi_data[6], mac_wifi_read[6];

    if(efuse_written_check(type, ui)) {
        LOGE("%s written already or something error\n", efuse_title[type]);
        return -1;
    }

    printf("prepate to write mac_wifi=%s\n", mac_wifi_str);
    memset(mac_wifi_data, 0, sizeof(mac_wifi_data));
    strcpy(buffer, mac_wifi_str);
	
    if((parg = strtok(buffer, ":")) == NULL) {
        printf("get mac:%s failed.\n", mac_wifi_str);
    }
    else {
        buf[0] = strdup(parg);
        for (i = 1; i < 100; i++) {
            if((parg = strtok(NULL, ":")) == NULL) {
                break;
            }
            else {
                buf[i] = strdup(parg);
            }
        }
    }

    data_size = i;
    printf("mac_wifi[%d]={", data_size, data_size);
    for(i=0; i<data_size; i++) {
        mac_wifi_data[i] = strtol(buf[i], NULL, 16);	
        if(i != data_size-1)
            printf("0x%02x,", mac_wifi_data[i]);
        else
            printf("0x%02x", mac_wifi_data[i]);
    }
    printf("}\n");

    printf("%s:%d\n", __func__, __LINE__);  
    if(6 == efuse_write(EFUSE_MAC_WIFI, (unsigned char *)mac_wifi_data, 6, ui)) {
        rc = 0;
    }	 

    //write success,test efuse read
    if(rc == 0) {
        printf("efuse write mac_wifi success,start to test efuse read mac_wifi...\n");
        memset(mac_wifi_read, 0, sizeof(mac_wifi_read));   
        if(6 == efuse_read(EFUSE_MAC_WIFI, mac_wifi_read, 6, ui)) {
            if(!memcmp(mac_wifi_data, mac_wifi_read, 6)) {
                printf("test efuse read mac_wifi success,read mac_wifi=%02x:%02x:%02x:%02x:%02x:%02x\n",
                        mac_wifi_read[0], mac_wifi_read[1], mac_wifi_read[2], mac_wifi_read[3], mac_wifi_read[4], mac_wifi_read[5]);
                rc = 0;
            }
            else {
                printf("test efuse read mac_wifi success,read mac_wifi=%02x:%02x:%02x:%02x:%02x:%02x,but not mach write\n",
                        mac_wifi_read[0], mac_wifi_read[1], mac_wifi_read[2], mac_wifi_read[3], mac_wifi_read[4], mac_wifi_read[5]);
                rc = -1;
            }
        }
    }	

    return rc;
 }

/**
  *  ---efuse_read_usid
  *  @usid_str: save usid key datas to this pointer
  *  @type: usid type
  *  @ui: recovery ui pointer
  *  return: 0->have writen before, 1->haven't write before, -1->read failed
  */
int efuse_read_usid(char *usid_str, int type, RecoveryUI* ui)
{
    int i, usid_flag = 0, rc = -1;
    int fd = -1;
    size_t count = 0;
    char usidData[512];
    
    efuseinfo_item_t efuseinfo_item;
    memset(&efuseinfo_item, 0, sizeof(efuseinfo_item_t));
    efuseinfo_item.id = efuse_id[EFUSE_USID];

    fd = efuse_opendev();
    if(fd >= 0) {
        if(ioctl(fd, EFUSE_INFO_GET, &efuseinfo_item)) {
            printf("efuse ioctl error\n");
            goto error;
        }
    }
    else {
        printf("efuse_opendev fail\n");
        goto error;
    }
    
    efuse_closedev(fd);
    count = efuseinfo_item.data_len;
    printf("usid max length is %d in efuse layout\n", count);

    printf("%s:%d\n", __func__, __LINE__);  
    memset(usid_str, 0, 512);
    memset(usidData, 0, sizeof(usidData));
    if(count == efuse_read(EFUSE_USID, usidData, count, ui)) {
        for(i=0; i<count; i++) {
            if(usidData[i] != 0x00) {
                usid_flag = 1;
                break;
            }
        }

        if(usid_flag) {
            rc = 0;				//have writen usid
            memcpy(usid_str, usidData, count);
            printf("efuse read usid success,usid=%s\n", usid_str);
        }
        else {
            rc = 1;				//haven't write usid	
            printf("haven't write usid before\n");
        }		
    }
	
    return rc;

error:
    printf("read efuse data %s error\n", efuse_title[EFUSE_USID]); 
    if(fd >= 0)
        efuse_closedev(fd);
    return -1 ;
}

/**
  *  ---efuse_write_usid
  *  @usid_str: usid key datas
  *  @type: usid type
  *  @ui: recovery ui pointer
  *  return: 0->write success, -1->write failed
  */
int efuse_write_usid(char *usid_str, int type, RecoveryUI* ui)
{
    int i, rc = -1;
    int fd = -1;
    size_t count = 0;
    char usid_data[512], usid_read[512];

    if(efuse_written_check(type, ui)) {
        LOGE("%s written already or something error\n", efuse_title[type]);
        return -1;
    }
    
    memset(usid_data, 0, sizeof(usid_data));
    memcpy(usid_data, usid_str, strlen(usid_str));
    printf("prepare to write usid=%s\n", usid_data);
    
    efuseinfo_item_t efuseinfo_item;
    memset(&efuseinfo_item, 0, sizeof(efuseinfo_item_t));
    efuseinfo_item.id = efuse_id[EFUSE_USID];
    
    fd  = efuse_opendev();
    if(fd >= 0) {
        if(ioctl(fd, EFUSE_INFO_GET, &efuseinfo_item)) {
            printf("efuse ioctl error\n");
            goto error;
        }
    }
    else {
        printf("efuse_opendev fail\n");
        goto error;
    }
    
    efuse_closedev(fd);
    count = efuseinfo_item.data_len;
    printf("usid max length is %d in efuse layout\n", count);

    printf("%s:%d\n", __func__, __LINE__);    
    if(count == efuse_write(EFUSE_USID, (unsigned char *)usid_data, count, ui)) {
        rc = 0;
        
        //write success,test efuse read
        printf("efuse write usid success,start to test efuse read usid...\n");
        memset(usid_read, 0, sizeof(usid_read));
        if(count == efuse_read(EFUSE_USID, (char*)usid_read, count, ui)) {
            if(!memcmp(usid_data, usid_read, count)) {
                printf("test efuse read usid success,read usid=%s\n", usid_read);
                rc = 0;     //write success,
            }
            else {
                printf("test efuse read usid success,read usid=%s,but not mach write\n", usid_read);
                rc = -1;    //if write success and read success, but read_data and write_data do not mach, then think to write fail
            }	
        }
        else
            rc = 0;         //if write success, but read fail, then think to write success
    }
    else
        rc = -1;            //write fail

    return rc;

error:
    printf("read efuse data %s error\n", efuse_title[EFUSE_USID]); 
    if(fd >= 0)
        efuse_closedev(fd);
    return -1 ;
}

/**
  *  ---efuse_read_hdcp
  *  @hdcp_str: save hdcp key datas to this pointer
  *  @type: hdcp type
  *  @ui: recovery ui pointer
  *  return: 0->have writen before, 1->haven't write before, -1->read failed
  */
int efuse_read_hdcp(char *hdcp_str, int type, RecoveryUI* ui)
{
    int i, hdcp_flag = 0, rc = -1;
    int fd = -1;
    size_t count = 0;
    char hdcpData[512];

    efuseinfo_item_t efuseinfo_item;
    memset(&efuseinfo_item, 0, sizeof(efuseinfo_item_t));
    efuseinfo_item.id = efuse_id[EFUSE_HDCP];

    fd  = efuse_opendev();
    if(fd >= 0) {
        if(ioctl(fd, EFUSE_INFO_GET, &efuseinfo_item)) {
            printf("efuse ioctl error\n");
            goto error;
        }
    }
    else {
        printf("efuse_opendev fail\n");
        goto error;
    }
    
    efuse_closedev(fd);
    count = efuseinfo_item.data_len;
    printf("hdcp max length is %d in efuse layout\n", count);

    printf("%s:%d\n", __func__, __LINE__);   
    memset(hdcp_str, 0, 512);
    memset(hdcpData, 0, sizeof(hdcpData));
    if(count == efuse_read(EFUSE_HDCP, hdcpData, count, ui)) {			
        for(i=0; i<count; i++) {
            if(hdcpData[i] != 0x00) {
                hdcp_flag = 1;
                break;
            }
        }

        if(hdcp_flag) {
            rc = 0;				//have writen hdcp
            memcpy(hdcp_str, hdcpData, count);
            printf("efuse read hdcp success,hdcp is:\n");
            for(i=0; i<count; i++)
                printf("%02x:",hdcp_str[i]);
            printf("\n");
        }
        else {
            rc = 1;				//haven't write hdcp	
            printf("haven't write hdcp before\n");
        }		
    }
	
    return rc;
    
error:
    printf("read efuse data %s error\n", efuse_title[EFUSE_USID]); 
    if(fd >= 0)
        efuse_closedev(fd);
    return -1 ;
}

/**
  *  ---efuse_write_hdcp
  *  @hdcp_str: hdcp key datas(288 keys at present)
  *  @type: hdcp type
  *  @ui: recovery ui pointer
  *  return: 0->write success, -1->write failed
  */
int efuse_write_hdcp(char *hdcp_str, int type, RecoveryUI* ui)
{
    int i, rc = -1, fd = -1;
    int hdcp_key_len = 288;
    size_t count = 0;
    char hdcp_data[512], hdcp_read[512];
    
    if (efuse_written_check(type, ui)) {
        LOGE("%s written already or something error\n", efuse_title[type]);
        return -1;
    }

    memset(hdcp_data, 0, sizeof(hdcp_data));
    memcpy(hdcp_data, hdcp_str, hdcp_key_len);  //copy 288 hdcp datas
    printf("prepare to write %d hdcp datas,hdcp is:\n", hdcp_key_len);
    for(i=0; i<hdcp_key_len; i++)
        printf("%02x:", hdcp_data[i]);
    printf("\n");	
	
    efuseinfo_item_t efuseinfo_item;
    memset(&efuseinfo_item, 0, sizeof(efuseinfo_item_t));
    efuseinfo_item.id = efuse_id[EFUSE_HDCP];
   
    fd  = efuse_opendev();
    if(fd >= 0) {
        if(ioctl(fd, EFUSE_INFO_GET, &efuseinfo_item)) {
            printf("efuse ioctl error\n");
            goto error;
        }
    }
    else {
        printf("efuse_opendev fail\n");
        goto error;
    }
    
    efuse_closedev(fd);
    count = efuseinfo_item.data_len;
    printf("hdcp max length is %d in efuse layout\n", count);
	
    printf("%s:%d\n", __func__, __LINE__);    
    if(count == efuse_write(EFUSE_HDCP, (unsigned char *)hdcp_data, count, ui)) {
        rc = 0;
        
        //write success,test efuse read
        printf("efuse write hdcp success,start to test efuse read hdcp...\n");
        memset(hdcp_read, 0, sizeof(hdcp_read));
        if(count == efuse_read(EFUSE_HDCP, (char*)hdcp_read, count, ui)) {
            if(!memcmp(hdcp_data, hdcp_read, count)) {
                printf("test efuse read hdcp success,read hdcp is:\n");
                for(i=0; i<count; i++)
                    printf("%02x:",hdcp_read[i]);
                printf("\n");	
                rc = 0;     //write success
            }
            else {
                printf("test efuse read hdcp success,but not mach write\n");
                rc = -1;    //if write success and read success, but read_data and write_data do not mach, then think to write fail
            }		
        }
        else
            rc = 0;	    //if write success, but read fail, then think to write success
    }
    else
        rc = -1;            //write fail

    return rc;

error:
    printf("read efuse data %s error\n", efuse_title[EFUSE_USID]); 
    if(fd >= 0)
        efuse_closedev(fd);
    return -1 ;
}


#define SECUKEY_BYTES 		512
#define PATH_KEY_NAME		"/sys/class/aml_keys/aml_keys/key_name"
#define PATH_KEY_READ 		"/sys/class/aml_keys/aml_keys/key_read"                      
static char hex_to_asc(char para)                                                                                                           
{
    if(para>=0 && para<=9)
        para = para+'0';
    else if(para>=0xa && para<=0xf)
        para = para+'a'-0xa;
         
    return para;
 }
 
 static char asc_to_hex(char para)
 {
    if(para>='0' && para<='9')
        para = para-'0';
    else if(para>='a' && para<='f')
        para = para-'a'+0xa;
    else if(para>='A' && para<='F')
        para = para-'A'+0xa;
         
    return para;
 }

/**
  *  ---flash_write_version -- init flash
  *  @path: flash key nodes path in kernel
  *  @version_str: don't work at present
  *  return: 0->init success, 1->already inited, -1->init failed
  */
int secukey_inited = 0;
int flash_write_version(char *path, char *version_str)
{
    FILE *fp;
    int size, rc= -1;
    char *buff = "auto3";

    printf("%s:%d\n", __func__, __LINE__);
    if(secukey_inited) {
        printf("flash device already inited!!\n");
        return 1;
    }
    printf("should be inited first!\n");
    
    printf("path=%s\n", path);
    fp = fopen(path, "w");
    if (fp == NULL) {
        printf("no %s found\n", path);
        return -1;
    }

    if(fwrite(buff, 1, strlen(buff), fp) == strlen(buff)) {
        printf("fwrite(...fp) success\n");
        printf("init flash device ok!!\n");
        rc = 0;
        secukey_inited = 1;
    }	
    else {
        printf("fwrite(...fp) failed\n");
        rc = -1;
    }

    fclose(fp);
    return rc;
}

/**
  *  ---flash_read_mac
  *  @path: flash key nodes path in kernel
  *  @mac_str: save mac key datas to this pointer
  *  return: 0->have writen before, 1->haven't write before, -1->read failed
  */
int flash_read_mac(char *path, char *mac_str)
{
    FILE *fp1=NULL, *fp2=NULL;
    int i, j, count, size, rc= -1, flag = 0;
    char *key_name = "mac", mac_read[2048], key_data[2048];

    printf("path=%s\n", path);
    memset(mac_read, 0, sizeof(mac_read));
    memset(key_data, 0, sizeof(key_data));
    memset(mac_str, 0, SECUKEY_BYTES);    

    fp1 = fopen(PATH_KEY_NAME, "w");
    if(fp1 == NULL) {
        printf("no %s found\n", PATH_KEY_NAME);
        return -1;
    }
    if(fp1 != NULL) {
        fp2 = fopen(path, "r");
        if (fp2 == NULL) {
            printf("no %s found\n", path);
            fclose(fp1);
            return -1;
        }
    }
    
    printf("%s:%d\n", __func__, __LINE__);
    if(fwrite(key_name, 1, strlen(key_name), fp1) == strlen(key_name)) {
        printf("fwrite(...fp1) success\n");
        fflush(fp1);
        count = fread(mac_read, 1, SECUKEY_BYTES*2, fp2);
        if(count >= 0) {
            printf("count=fread(...fp2)=%d\n", count);
            if(ferror(fp2)) {	
                printf("error reading from %s\n", path);
                clearerr(fp2);
            }

            for(i=0,j=0; i<SECUKEY_BYTES*2; i++,j++){
                key_data[j] = (((asc_to_hex(mac_read[i]))<<4) | (asc_to_hex(mac_read[i+1])));
                i++;
            }

            for(i=0; i<SECUKEY_BYTES; i++) {
                if(key_data[i] !=0x00) {
                    flag = 1;
                    break;
                }
            }
            if(flag) {
                rc = 0;								//have writen mac
                memcpy(mac_str, key_data, SECUKEY_BYTES);
                printf("flash read mac success,mac=%s\n", mac_str);
            }
            else {
                rc = 1;								//haven't write mac
                printf("haven't write mac before\n");
            }
           
        }	
    }
    else
        printf("fwrite(...fp1) failed\n");

    if(NULL != fp2) {
        fclose(fp2);
        fp2 = NULL;
    }
    if(NULL != fp1) {
        fclose(fp1);
        fp1 = NULL;
    }

    return rc;
}

/**
  *  ---flash_write_mac
  *  @path: flash key nodes path in kernel
  *  @mac_str: mac key datas
  *  return: 0->write success, -1->write failed
  */
int flash_write_mac(char *path, char *mac_str)
{
    FILE *fp1=NULL, *fp2=NULL;
    int i, j, mac_len=0, count, size, rc= -1;
    char *key_name = "mac";
    char key_data[2048], mac_data[2048], mac_read[2048];

    memset(key_data, 0, sizeof(key_data));
    memset(mac_data, 0, sizeof(mac_data));
    memset(mac_read, 0, sizeof(mac_read));
    
    mac_len =  strlen(mac_str);
    printf("path=%s\n", path);
    printf("prepare to write %d mac length,mac=%s\n", mac_len, mac_str);

    for(i=0,j=0; i<mac_len; i++,j++){
        mac_data[j]= hex_to_asc((mac_str[i]>>4) & 0x0f);
        mac_data[++j] = hex_to_asc((mac_str[i]) & 0x0f);
        printf("%02x:%02x:", mac_data[j-1], mac_data[j]);
    } 
    printf("\n");

    fp1 = fopen(PATH_KEY_NAME, "w");
    if(fp1 == NULL) {
        printf("no %s found\n", PATH_KEY_NAME);
        goto error;
    }
    if(fp1 != NULL){
        fp2 = fopen(path, "w");
        if (fp2 == NULL) {
            printf("no %s found\n", path);
            goto error;
        }
    }
    
    printf("%s:%d\n", __func__, __LINE__);
    if(fwrite(key_name, 1, strlen(key_name), fp1) == strlen(key_name)) {
        printf("fwrite(...fp1) success\n");
        if(fwrite(mac_data, 1, mac_len*2, fp2) == mac_len*2) {
            printf("fwrite(...fp2) success\n");
            rc = 0;

            fclose(fp1);
            fp1 = NULL;
            fclose(fp2);
            fp2 = NULL;
            
            //write success,test flash read
            printf("flash write mac success,start to test flash read mac...\n");
            fp1 = fopen(PATH_KEY_NAME, "w");
            if (fp1 == NULL) {
                printf("no %s found\n", PATH_KEY_NAME);
                goto error;
            }
            if(fp1 != NULL){
                fp2 = fopen(PATH_KEY_READ, "r");
                if(fp2 == NULL) {
                    printf("no %s found\n", PATH_KEY_READ);
                    goto error;
                }
            }
            if(fwrite(key_name, 1, strlen(key_name), fp1) == strlen(key_name)) {
                printf("fwrite(...fp1) success\n");
                fflush(fp1);
                count = fread(mac_read, 1, SECUKEY_BYTES*2, fp2);
                if(count >= 0) {
                    printf("count=fread(...fp2)=%d\n", count);
                    if(ferror(fp2)) {
                        printf("error reading from %s\n", path);
                        clearerr(fp2);
                    }

                    for(i=0,j=0; i<SECUKEY_BYTES*2; i++,j++){
                        key_data[j]= (((asc_to_hex(mac_read[i]))<<4) | (asc_to_hex(mac_read[i+1])));
                        i++;
                    }
                    printf("have writen mac data=%s\n", mac_str);
                    printf("test read mac data=%s\n", key_data);

                    if(!memcmp(key_data, mac_str, mac_len)) {
                        printf("test flash read mac success,read mac=%s\n", key_data);
                        rc = 0;
                    }
                    else {
                        printf("test flash read mac success,read mac=%s,but not mach write\n", key_data);
                        rc = -1;
                    }
                }	
            }
        }
        else {
            printf("fwrite(...fp2) failed\n");
            rc = -1;
        }
    }
    else
        printf("fwrite(...fp1) failed\n");

error:
    if (NULL != fp2) {
        fclose(fp2);
        fp2 = NULL;
    }
    if (NULL != fp1) {
        fclose(fp1);
        fp1 = NULL;
    }

    return rc;
}

/**
  *  ---flash_read_mac_bt
  *  @path: flash key nodes path in kernel
  *  @mac_bt_str: save mac_bt key datas to this pointer
  *  return: 0->have writen before, 1->haven't write before, -1->read failed
  */
int flash_read_mac_bt(char *path, char *mac_bt_str)
{
    FILE *fp1=NULL, *fp2=NULL;
    int i, j, count, size, rc= -1, flag = 0;
    char *key_name = "mac_bt", mac_bt_read[2048], key_data[2048];

    printf("path=%s\n", path);
    memset(mac_bt_read, 0, sizeof(mac_bt_read));
    memset(key_data, 0, sizeof(key_data));
    memset(mac_bt_str, 0, SECUKEY_BYTES);    

    fp1 = fopen(PATH_KEY_NAME, "w");
    if(fp1 == NULL) {
        printf("no %s found\n", PATH_KEY_NAME);
        return -1;
    }
    if(fp1 != NULL) {
        fp2 = fopen(path, "r");
        if (fp2 == NULL) {
            printf("no %s found\n", path);
            fclose(fp1);
            return -1;
        }
    }

    printf("%s:%d\n", __func__, __LINE__);
    if(fwrite(key_name, 1, strlen(key_name), fp1) == strlen(key_name)) {
        printf("fwrite(...fp1) success\n");
        fflush(fp1);
        count = fread(mac_bt_read, 1, SECUKEY_BYTES*2, fp2);
        if(count >= 0) {
            printf("count=fread(...fp2)=%d\n", count);
            if(ferror(fp2)) {
                printf("error reading from %s\n", path);
                clearerr(fp2);
            }

            for(i=0,j=0; i<SECUKEY_BYTES*2; i++,j++){
                key_data[j] = (((asc_to_hex(mac_bt_read[i]))<<4) | (asc_to_hex(mac_bt_read[i+1])));
                i++;
            }

            for(i=0; i<SECUKEY_BYTES; i++) {
                if(key_data[i] !=0x00) {
                    flag = 1;
                    break;
                }
            }
            if(flag) {
                rc = 0;								//have writen mac_bt
                memcpy(mac_bt_str, key_data, SECUKEY_BYTES);
                printf("flash read mac_bt success,mac_bt=%s\n", mac_bt_str);
            }
            else {
                rc = 1;								//haven't write mac_bt
                printf("haven't write mac_bt before\n");
            }
        }	
    }
    else
        printf("fwrite(...fp1) failed\n");

    if(NULL != fp2) {
        fclose(fp2);
        fp2 = NULL;
    }
    if(NULL != fp1) {
        fclose(fp1);
        fp1 = NULL;
    }

    return rc;
}

/**
  *  ---flash_write_mac_bt
  *  @path: flash key nodes path in kernel
  *  @mac_bt_str: mac_bt key datas
  *  return: 0->write success, -1->write failed
  */
int flash_write_mac_bt(char *path, char *mac_bt_str)
{
    FILE *fp1=NULL, *fp2=NULL;
    int i, j, mac_bt_len=0, count, size, rc= -1;
    char *key_name = "mac_bt";
    char key_data[2048], mac_bt_data[2048], mac_bt_read[2048];

    memset(key_data, 0, sizeof(key_data));
    memset(mac_bt_data, 0, sizeof(mac_bt_data));
    memset(mac_bt_read, 0, sizeof(mac_bt_read));
    
    mac_bt_len =  strlen(mac_bt_str);
    printf("path=%s\n", path);
    printf("prepare to write %d mac_bt length,mac_bt=%s\n", mac_bt_len, mac_bt_str);

    for(i=0,j=0; i<mac_bt_len; i++,j++){
        mac_bt_data[j] = hex_to_asc((mac_bt_str[i]>>4) & 0x0f);
        mac_bt_data[++j] = hex_to_asc((mac_bt_str[i]) & 0x0f);
        printf("%02x:%02x:", mac_bt_data[j-1], mac_bt_data[j]);
    } 
    printf("\n");

    fp1 = fopen(PATH_KEY_NAME, "w");
    if(fp1 == NULL) {
        printf("no %s found\n", PATH_KEY_NAME);
        goto error;
    }
    if(fp1 != NULL) {
        fp2 = fopen(path, "w");
        if (fp2 == NULL) {
            printf("no %s found\n", path);
            goto error;
        }
    }

    printf("%s:%d\n", __func__, __LINE__);
    if(fwrite(key_name, 1, strlen(key_name), fp1) == strlen(key_name)) {
        printf("fwrite(...fp1) success\n");
        if(fwrite(mac_bt_data, 1, mac_bt_len*2, fp2) == mac_bt_len*2) {
            printf("fwrite(...fp2) success\n");
            rc = 0;

            fclose(fp1);
            fp1 = NULL;
            fclose(fp2);
            fp2 = NULL;
            
            //write success,test flash read
            printf("flash write mac_bt success,start to test flash read mac_bt...\n");
            fp1 = fopen(PATH_KEY_NAME, "w");
            if (fp1 == NULL) {
                printf("no %s found\n", PATH_KEY_NAME);
                goto error;
            }
            if(fp1 != NULL){
                fp2 = fopen(PATH_KEY_READ, "r");
                if(fp2 == NULL) {
                    printf("no %s found\n", PATH_KEY_READ);
                    goto error;
                }
            }
            if(fwrite(key_name, 1, strlen(key_name), fp1) == strlen(key_name)) {
                printf("fwrite(...fp1) success\n");
                fflush(fp1);
                count = fread(mac_bt_read, 1, SECUKEY_BYTES*2, fp2);
                if(count >= 0) {
                    printf("count=fread(...fp2)=%d\n", count);
                    if(ferror(fp2)) {
                        printf("error reading from %s\n", path);
                        clearerr(fp2);
                    }

                    for(i=0,j=0; i<SECUKEY_BYTES*2; i++,j++){
                        key_data[j] = (((asc_to_hex(mac_bt_read[i]))<<4) | (asc_to_hex(mac_bt_read[i+1])));
                        i++;
                    }
                    printf("have writen mac_bt data=%s\n", mac_bt_str);
                    printf("test read mac_bt data=%s\n", key_data);

                    if(!memcmp(key_data, mac_bt_str, mac_bt_len)) {
                        printf("test flash read mac_bt success,read mac_bt=%s\n", key_data);
                        rc = 0;
                    }
                    else {
                        printf("test flash read mac_bt success,read mac_bt=%s,but not mach write\n", key_data);
                        rc = -1;
                    }
                }	
            }
        }
        else {
            printf("fwrite(...fp2) failed\n");
            rc = -1;
        }
    }
    else
        printf("fwrite(...fp1) failed\n");

error:
    if (NULL != fp2) {
        fclose(fp2);
        fp2 = NULL;
    }
    if (NULL != fp1) {
        fclose(fp1);
        fp1 = NULL;
    }

    return rc;
}

/**
  *  ---flash_read_mac_wifi
  *  @path: flash key nodes path in kernel
  *  @mac_wifi_str: save mac_wifi key datas to this pointer
  *  return: 0->have writen before, 1->haven't write before, -1->read failed
  */
int flash_read_mac_wifi(char *path, char *mac_wifi_str)
{
    FILE *fp1=NULL, *fp2=NULL;
    int i, j, count, size, rc= -1, flag = 0;
    char *key_name = "mac_wifi", mac_wifi_read[2048], key_data[2048];

    printf("path=%s\n", path);
    memset(mac_wifi_read, 0, sizeof(mac_wifi_read));
    memset(key_data, 0, sizeof(key_data));
    memset(mac_wifi_str, 0, SECUKEY_BYTES);    

    fp1 = fopen(PATH_KEY_NAME, "w");
    if(fp1 == NULL) {
        printf("no %s found\n", PATH_KEY_NAME);
        return -1;
    }
    if(fp1 != NULL) {
        fp2 = fopen(path, "r");
        if (fp2 == NULL) {
            printf("no %s found\n", path);
            fclose(fp1);
            return -1;
        }
    }

    printf("%s:%d\n", __func__, __LINE__);
    if(fwrite(key_name, 1, strlen(key_name), fp1) == strlen(key_name)) {
        printf("fwrite(...fp1) success\n");
        fflush(fp1);
        count = fread(mac_wifi_read, 1, SECUKEY_BYTES*2, fp2);
        if(count >= 0) {
            printf("count=fread(...fp2)=%d\n", count);
            if(ferror(fp2)) {	
                printf("error reading from %s\n", path);
                clearerr(fp2);
            }
            
            for(i=0,j=0; i<SECUKEY_BYTES*2; i++,j++){
                key_data[j] = (((asc_to_hex(mac_wifi_read[i]))<<4) | (asc_to_hex(mac_wifi_read[i+1])));
                i++;
            }

            for(i=0; i<SECUKEY_BYTES; i++) {
                if(key_data[i] !=0x00) {
                    flag = 1;
                    break;
                }
            }
            if(flag) {
                rc = 0;								//have writen mac_wifi
                memcpy(mac_wifi_str, key_data, SECUKEY_BYTES);
                printf("flash read mac_wifi success,mac_wifi=%s\n", mac_wifi_str);
            }
            else {
                rc = 1;								//haven't write mac_wifi
                printf("haven't write mac_wifi before\n");
            }
        }	
    }
    else
        printf("fwrite(...fp1) failed\n");

    if(NULL != fp2) {
        fclose(fp2);
        fp2 = NULL;
    }
    if(NULL != fp1) {
        fclose(fp1);
        fp1 = NULL;
    }

    return rc;
}

/**
  *  ---flash_write_mac_wifi
  *  @path: flash key nodes path in kernel
  *  @mac_wifi_str: mac_wifi key datas
  *  return: 0->write success, -1->write failed
  */
int flash_write_mac_wifi(char *path, char *mac_wifi_str)
{
    FILE *fp1=NULL, *fp2=NULL;
    int i, j, mac_wifi_len=0, count, size, rc= -1;
    char *key_name = "mac_wifi";
    char key_data[2048], mac_wifi_data[2048], mac_wifi_read[2048];

    memset(key_data, 0, sizeof(key_data));
    memset(mac_wifi_data, 0, sizeof(mac_wifi_data));
    memset(mac_wifi_read, 0, sizeof(mac_wifi_read));
    
    mac_wifi_len =  strlen(mac_wifi_str);
    printf("path=%s\n", path);
    printf("prepare to write %d mac_wifi length,mac_wifi=%s\n", mac_wifi_len, mac_wifi_str);

    for(i=0,j=0; i<mac_wifi_len; i++,j++){
        mac_wifi_data[j] = hex_to_asc((mac_wifi_str[i]>>4) & 0x0f);
        mac_wifi_data[++j] = hex_to_asc((mac_wifi_str[i]) & 0x0f);
        printf("%02x:%02x:", mac_wifi_data[j-1], mac_wifi_data[j]);
    } 
    printf("\n");

    fp1 = fopen(PATH_KEY_NAME, "w");
    if(fp1 == NULL) {
        printf("no %s found\n", PATH_KEY_NAME);
        goto error;
    }
    if(fp1 != NULL) {
        fp2 = fopen(path, "w");
        if (fp2 == NULL) {
            printf("no %s found\n", path);
            goto error;
        }
    }

    printf("%s:%d\n", __func__, __LINE__);
    if(fwrite(key_name, 1, strlen(key_name), fp1) == strlen(key_name)) {
        printf("fwrite(...fp1) success\n");
        if(fwrite(mac_wifi_data, 1, mac_wifi_len*2, fp2) == mac_wifi_len*2) {
            printf("fwrite(...fp2) success\n");
            rc = 0;

            fclose(fp1);
            fp1 = NULL;
            fclose(fp2);
            fp2 = NULL;
            
            //write success,test flash read
            printf("flash write mac_wifi success,start to test flash read mac_wifi...\n");
            fp1 = fopen(PATH_KEY_NAME, "w");
            if (fp1 == NULL) {
                printf("no %s found\n", PATH_KEY_NAME);
                goto error;
            }
            if(fp1 != NULL){
                fp2 = fopen(PATH_KEY_READ, "r");
                if(fp2 == NULL) {
                    printf("no %s found\n", PATH_KEY_READ);
                    goto error;
                }
            }
            if(fwrite(key_name, 1, strlen(key_name), fp1) == strlen(key_name)) {
                printf("fwrite(...fp1) success\n");
                fflush(fp1);
                count = fread(mac_wifi_read, 1, SECUKEY_BYTES*2, fp2);
                if(count >= 0) {
                    printf("count=fread(...fp2)=%d\n", count);
                    if(ferror(fp2)) {
                        printf("error reading from %s\n", path);
                        clearerr(fp2);
                    }

                    for(i=0,j=0; i<SECUKEY_BYTES*2; i++,j++){
                        key_data[j] = (((asc_to_hex(mac_wifi_read[i]))<<4) | (asc_to_hex(mac_wifi_read[i+1])));
                        i++;
                    }
                    printf("have writen mac_wifi data=%s\n", mac_wifi_str);
                    printf("test read mac_wifi data=%s\n", key_data);

                    if(!memcmp(key_data, mac_wifi_str, mac_wifi_len)) {
                        printf("test flash read mac_wifi success,read mac_wifi=%s\n", key_data);
                        rc = 0;
                    }
                    else {
                        printf("test flash read mac_wifi success,read mac_wifi=%s,but not mach write\n", key_data);
                        rc = -1;
                    }
                }	
            }
        }
        else {
            printf("fwrite(...fp2) failed\n");
            rc = -1;
        }
    }
    else
        printf("fwrite(...fp1) failed\n");

error:
    if (NULL != fp2) {
        fclose(fp2);
        fp2 = NULL;
    }
    if (NULL != fp1) {
        fclose(fp1);
        fp1 = NULL;
    }

    return rc;
}

/**
  *  ---flash_read_usid
  *  @path: flash key nodes path in kernel
  *  @usid_str: save usid key datas to this pointer
  *  return: 0->have writen before, 1->haven't write before, -1->read failed
  */
int flash_read_usid(char *path, char *usid_str)
{
    FILE *fp1=NULL, *fp2=NULL;
    int i, j, count, size, rc= -1, usid_flag = 0;
    char *key_name = "usid", key_data[2048], usid_read[2048];

    printf("path=%s\n", path);
    memset(key_data, 0, sizeof(key_data));
    memset(usid_read, 0, sizeof(usid_read));
    memset(usid_str, 0, SECUKEY_BYTES);  
    
    fp1 = fopen(PATH_KEY_NAME, "w");
    if (fp1 == NULL) {
        printf("no %s found\n", PATH_KEY_NAME);
        return -1;
    }
    if(fp1 != NULL){
        fp2 = fopen(path, "r");
        if(fp2 == NULL) {
            printf("no %s found\n", path);
            fclose(fp1);
            return -1;
        }	
    }	

    printf("%s:%d\n", __func__, __LINE__);
    if(fwrite(key_name, 1, strlen(key_name), fp1) == strlen(key_name)) {
        printf("fwrite(...fp1) success\n");
        fflush(fp1);
        count = fread(usid_read, 1, SECUKEY_BYTES*2, fp2);								
        if(count >= 0) {
            printf("count=fread(...fp2)=%d\n",count);
            if(ferror(fp2)) {	
                printf("error reading from %s\n",path); 
                clearerr(fp2);
            }	
            
            for(i=0,j=0; i<SECUKEY_BYTES*2; i++,j++){                                                                     
                key_data[j] = (((asc_to_hex(usid_read[i]))<<4) | (asc_to_hex(usid_read[i+1])));
                i++;
            }
            
            for(i=0; i<SECUKEY_BYTES; i++) {
                if(key_data[i] !=0x00) {	
                    usid_flag = 1;
                    break;
                }
            }	
            if(usid_flag) {
                rc = 0;								//have writen usid
                memcpy(usid_str, key_data, SECUKEY_BYTES);
                printf("flash read usid success,usid=%s\n", usid_str);
            }	
            else {
                rc = 1;								//haven't write usid	
                printf("haven't write usid before\n");
            }
        }										
    }	
    else
        printf("fwrite(...fp1) failed\n");	
	
	if (NULL != fp2)
	{
		fclose(fp2);
		fp2 = NULL;
	}
	if (NULL != fp1)
	{
		fclose(fp1);
		fp1 = NULL;
	}
	
	return rc;

}

/**
  *  ---flash_write_usid
  *  @path: flash key nodes path in kernel
  *  @usid_str: usid key datas
  *  return: 0->write success, -1->write failed
  */
int flash_write_usid(char *path, char *usid_str)
{
    FILE *fp1=NULL, *fp2=NULL;
    int i, j, usid_len=0, count, size, rc= -1;
    char *key_name = "usid";
    char key_data[2048], usid_data[2048], usid_read[2048];

    memset(key_data, 0, sizeof(key_data));
    memset(usid_data, 0, sizeof(usid_data));
    memset(usid_read, 0, sizeof(usid_read));

    usid_len = strlen(usid_str);
    printf("path=%s\n", path);		
    printf("prepare to write %d usid length,usid=%s\n", usid_len, usid_str);

    for(i=0,j=0; i<usid_len; i++,j++){
        usid_data[j] = hex_to_asc((usid_str[i]>>4) & 0x0f);
        usid_data[++j] = hex_to_asc((usid_str[i]) & 0x0f);
        printf("%02x:%02x:", usid_data[j-1], usid_data[j]);
    } 
    printf("\n");

    fp1 = fopen(PATH_KEY_NAME, "w");
    if(fp1 == NULL) {
        printf("no %s found\n", PATH_KEY_NAME);
        goto error;
    }

    if(fp1 != NULL){
        fp2 = fopen(path, "w");
        if(fp2 == NULL) {
            printf("no %s found\n", path);
            goto error;
        }	
    }	

    printf("%s:%d\n", __func__, __LINE__);
    if(fwrite(key_name, 1, strlen(key_name), fp1) == strlen(key_name)) {
        printf("fwrite(...fp1) success\n");
        if(fwrite(usid_data, 1, usid_len*2, fp2) == usid_len*2) {
            printf("fwrite(...fp2) success\n");
            rc = 0;                     //write success
			
            fclose(fp1);
            fp1 = NULL;
            fclose(fp2);
            fp2 = NULL;

            //write success,test flash read
            printf("flash write usid success,start to test flash read usid...\n");
            fp1 = fopen(PATH_KEY_NAME, "w");
            if (fp1 == NULL) {
                printf("no %s found\n", PATH_KEY_NAME);
                goto error;
            }
            if(fp1 != NULL) {
                fp2 = fopen(PATH_KEY_READ, "r");
                if (fp2 == NULL) {
                    printf("no %s found\n", PATH_KEY_READ);
                    goto error;
                }	
            }
            if(fwrite(key_name, 1, strlen(key_name), fp1) == strlen(key_name)) {
                printf("fwrite(...fp1) success\n");
                fflush(fp1);
                count = fread(usid_read, 1, SECUKEY_BYTES*2, fp2);  
                if(count >= 0) {
                    printf("count=fread(...fp2)=%d\n", count);		
                    if(ferror(fp2)) {
                        printf("error reading from %s\n", path); 
                        clearerr(fp2);
                    }

                    for (i=0,j=0; i<SECUKEY_BYTES*2; i++,j++){
                        key_data[j] = (((asc_to_hex(usid_read[i]))<<4) | (asc_to_hex(usid_read[i+1])));
                        i++;
                    }
                    printf("have writen usid data=%s\n", usid_str);	
                    printf("test read usid data=%s\n", key_data);

                    if(!memcmp(key_data, usid_str, usid_len)) {
                        printf("test flash read usid success,read usid=%s\n", key_data);
                        rc = 0;
                    }
                    else {
                        printf("test flash read usid success,read usid=%s,but not mach write\n", key_data);
                        rc = -1;    //if write success and read success, but read_data and write_data do not mach, then think to write fail
                    }			
                }			
            }
        }	
        else {
            printf("fwrite(...fp2) failed\n");
            rc = -1;
        }	
    }
    else
        printf("fwrite(...fp1) failed\n");

error:
    if(NULL != fp2) {
        fclose(fp2);
        fp2 = NULL;
    }
    if(NULL != fp1) {
        fclose(fp1);
        fp1 = NULL;
    }
	
    return rc;
}

/**
  *  ---flash_read_hdcp
  *  @path: flash key nodes path in kernel
  *  @hdcp_str: save hdcp key datas to this pointer
  *  return: 0->have writen before, 1->haven't write before, -1->read failed
  */
int flash_read_hdcp(char *path, char *hdcp_str)
{
    FILE *fp1=NULL, *fp2=NULL;
    int i, j, count, size, rc= -1, hdcp_flag = 0;
    char *key_name = "hdcp", key_data[2048], hdcp_read[2048];

    printf("path=%s\n", path);
    memset(key_data, 0, sizeof(key_data));
    memset(hdcp_read, 0, sizeof(hdcp_read));
    memset(hdcp_str, 0, SECUKEY_BYTES);  
    
    fp1 = fopen(PATH_KEY_NAME, "w");
    if(fp1 == NULL) {
        printf("no %s found\n", PATH_KEY_NAME);
        return -1;
    }
    if(fp1 != NULL){
        fp2 = fopen(path, "r");
        if(fp2 == NULL) {
            printf("no %s found\n", path);
            fclose(fp1);
            return -1;
        }	
    }	
    
    printf("%s:%d\n", __func__, __LINE__);
    if(fwrite(key_name, 1, strlen(key_name), fp1) == strlen(key_name)) {
        printf("fwrite(...fp1) success\n");
        fflush(fp1);
        count = fread(hdcp_read,  1, SECUKEY_BYTES*2, fp2);
        if(count >= 0) {
            printf("count=fread(...fp2)=%d\n",count);
            if(ferror(fp2)) {
                printf("error reading from %s\n",path); 
                clearerr(fp2);
            }
            
            for(i=0,j=0; i<SECUKEY_BYTES*2; i++,j++){                                                                     
                key_data[j] = (((asc_to_hex(hdcp_read[i]))<<4) | (asc_to_hex(hdcp_read[i+1])));
                i++;
            }

            for(i=0; i<SECUKEY_BYTES; i++) {
                if(key_data[i] !=0x00) {	
                    hdcp_flag = 1;
                    break;
                }
            }	
            if(hdcp_flag) {
                rc = 0;								//have writen hdcp
                memcpy(hdcp_str, key_data, SECUKEY_BYTES);
                printf("flash read hdcp success,hdcp is:\n");	
                for(i=0; i<SECUKEY_BYTES; i++)
                    printf("%02x:", key_data[i]);
                printf("\n");
            }	
            else {
                rc = 1;								//haven't write hdcp	
                printf("haven't write hdcp before\n");
            }
        }				
    }	
    else
        printf("fwrite(...fp1) failed\n");	
	
    if (NULL != fp2) {
        fclose(fp2);
        fp2 = NULL;
    }
    if (NULL != fp1) {
        fclose(fp1);
        fp1 = NULL;
    }
	
    return rc;
}

/**
  *  ---flash_write_hdcp
  *  @path: flash key nodes path in kernel
  *  @hdcp_str: hdcp key datas(288 keys at present)
  *  return: 0->write success, -1->write failed
  */
int flash_write_hdcp(char *path, char *hdcp_str)
{
    FILE *fp1=NULL, *fp2=NULL;
    int i, j, count, size, rc= -1;
    char *key_name = "hdcp";
    char key_data[2048], hdcp_data[2048], hdcp_read[2048];
    int hdcp_key_len = 288;
    
    printf("path=%s\n", path);	
    memset(key_data, 0, sizeof(key_data));
    memset(hdcp_data, 0, sizeof(hdcp_data));
    memset(hdcp_read, 0, sizeof(hdcp_read));

    printf("prepare to write %d hdcp datas,hdcp is:\n", hdcp_key_len);
    for(i=0; i<hdcp_key_len; i++)
         printf("%02x:", hdcp_str[i]);
    printf("\n");
    
    for (i=0,j=0; i<hdcp_key_len; i++,j++){
        hdcp_data[j] = hex_to_asc((hdcp_str[i]>>4) & 0x0f);
        hdcp_data[++j] = hex_to_asc((hdcp_str[i]) & 0x0f);
        printf("%02x:%02x:", hdcp_data[j-1], hdcp_data[j]);
    } 
    printf("\n");

    fp1 = fopen(PATH_KEY_NAME, "w");
    if(fp1 == NULL) {
        printf("no %s found\n", PATH_KEY_NAME);
        goto error;
    }
    if(fp1 != NULL){
        fp2 = fopen(path, "w");
        if(fp2 == NULL) {
            printf("no %s found\n", path);
            goto error;
        }	
    }	

    printf("%s:%d\n", __func__, __LINE__);
    if(fwrite(key_name, 1, strlen(key_name), fp1) == strlen(key_name)) {
        printf("fwrite(...fp1) success\n");
        if(fwrite(hdcp_data, 1, hdcp_key_len*2, fp2) == hdcp_key_len*2)	{
            printf("fwrite(...fp2) success\n");
            rc = 0;                     //write success
			
            fclose(fp1);
            fp1 = NULL;
            fclose(fp2);
            fp2 = NULL;
            
            //write success,test flash read
            printf("flash write hdcp success,start to test flash read hdcp...\n");
            fp1 = fopen(PATH_KEY_NAME, "w");
            if (fp1 == NULL) {
                printf("no %s found\n", PATH_KEY_NAME);
                goto error;
            }
            if(fp1 != NULL){
                fp2 = fopen(PATH_KEY_READ, "r");
                if(fp2 == NULL) {
                    printf("no %s found\n", PATH_KEY_READ);
                    goto error;
                }	
            }
            if(fwrite(key_name, 1, strlen(key_name), fp1) == strlen(key_name)) {
                printf("fwrite(...fp1) success\n");
                fflush(fp1);
                count = fread(hdcp_read, 1, SECUKEY_BYTES*2, fp2);  
                if(count >= 0) {
                    printf("count=fread(...fp2)=%d\n",count);		
                    if(ferror(fp2)) {
                        printf("error reading from %s\n",path); 
                        clearerr(fp2);
                    }
                    
                    for(i=0,j=0; i<SECUKEY_BYTES*2; i++,j++){
                        key_data[j] = (((asc_to_hex(hdcp_read[i]))<<4) | (asc_to_hex(hdcp_read[i+1])));
                        i++;
                    }

                    if(!memcmp(key_data, hdcp_str, hdcp_key_len)) {
                        printf("test flash read hdcp success,read hdcp is:\n");
                        for(i=0; i<hdcp_key_len; i++)
                            printf("%02x:", key_data[i]);
                        printf("\n");
                        rc = 0;
                    }
                    else {
                        printf("test flash read hdcp success,but not mach write\n");
                        rc = -1;        //if write success and read success, but read_data and write_data do not mach, then think to write fail
                    }								
                }
            }
        }	
        else {
            printf("fwrite(...fp2) failed\n");
            rc = -1;
        }	
    }
    else
        printf("fwrite(...fp1) failed\n");

error:
    if (NULL != fp2) {
        fclose(fp2);
        fp2 = NULL;
    }
    if (NULL != fp1) {
        fclose(fp1);
        fp1 = NULL;
    }
	
    return rc;
}


#ifdef SDCARD_EFUSE_MAC_ENABLE
static int
efuse_write_mac(const char *path, int type, RecoveryUI* ui)
{
    FILE *fp;
    char *rbuff = NULL, *wbuff = NULL;
    char *line;
    int size, rc, error = 0, offset = 0;
    unsigned char mac[6];

    ui->Print("Finding %s...\n", efuse_title[type]);

    fp = fopen_path(path, "r");
    if (fp == NULL) {
        LOGE("no %s found\n", efuse_title[type]);
        return -1;
    }

    if (efuse_written_check(type, ui)) {
        LOGE("%s written already or something error\n", efuse_title[type]);
        return -1;
    }

    fseek(fp, 0, SEEK_END);
    size = ftell(fp);

    LOGI("efuse_update_mac() path=%s type=%s size=%d\n", path, efuse_title[type], size);

    ui->Print("Reading %s...\n", efuse_title[type]);

    rbuff = (char *)malloc(size + 1);
    wbuff = (char *)malloc(size + 2);
    if (rbuff == NULL || wbuff == NULL) {
        LOGE("system out of resource\n");
        if (rbuff) free(rbuff);
        if (wbuff) free(wbuff);
        check_and_fclose(fp, path);
        return -1;
    }

    fseek(fp, 0, SEEK_SET);
    if ((int)fread(rbuff, 1, size, fp) != size) {
        LOGE("invalid %s\n", efuse_title[type]);
        if (rbuff) free(rbuff);
        if (wbuff) free(wbuff);
        check_and_fclose(fp, path);
        return -1;
    }

    rc = 0;
    rbuff[size] = '\0';
    check_and_fclose(fp, path);

    line = strtok(rbuff, "\n");
    do {
        if (*line == '$' || (strlen(line) != EFUSE_MACLEN && strlen(line) != EFUSE_MACLEN + 1)) {
            offset += strlen(line) + 1 ;
            LOGI("efuse_update_mac() line=\"%s\" SKIP offset=%d\n", line, offset);
            continue;
        }
        for (rc = 0; rc < EFUSE_MACLEN; rc += 3) {
            if (isxdigit(line[rc]) && isxdigit(line[rc + 1]) && (line[rc + 2] == ':' || line[rc + 2] == '\0' || line[rc + 2] == '\r')) {
                mac[rc / 3] = ((isdigit(line[rc]) ? line[rc] - '0' : toupper(line[rc]) - 'A' + 10) << 4) |
                               (isdigit(line[rc + 1]) ? line[rc + 1] - '0' : toupper(line[rc + 1]) - 'A' + 10);
            }
            else
                break;
        }

        if (rc == EFUSE_MACLEN + 1) {
            LOGI("efuse_update_mac() line=\"%s\" MATCH\n", line);

            ui->Print("Writing %s %02x:%02x:%02x:%02x:%02x:%02x\n", efuse_title[type], mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);

            if (6 == efuse_write(type, mac, 6, ui)) {
                fp = fopen_path(path, "r");
                if (fp) {
                    fread(rbuff, 1, size, fp);
                    rbuff[size] = '\0';
                    check_and_fclose(fp, path);

                    fp = fopen_path(path, "w+");
                    if (fp) {
                        line = wbuff;
                        memset(wbuff, 0, size + 2);
                        memcpy(line, rbuff, offset);
                        *(line + offset) = '$';
                        memcpy(line + offset + 1, rbuff + offset, size - offset);
                        offset = fwrite(wbuff, 1, size + 1, fp);
                        LOGI("efuse_update_mac() %s wrote rc=%d size=%d\n", path, offset, size + 2);
                        if (offset != size + 1) {
                            error++;
                            LOGE("error updating %s\n", efuse_title[type]);
                        }
                        check_and_fclose(fp, path);
                    }
                }
            }
            else {
                error++;
                LOGE("efuse write error\n");
            }

            break;
        }
        else {
            offset += strlen(line) + 1;
            LOGI("efuse_update_mac() line=\"%s\" INVALID offset=%d\n", line, offset);
        }
    } while((line = strtok(NULL,"\n")));

    if (rc != EFUSE_MACLEN + 1)
        ui->Print("No %s found\n", efuse_title[type]);

    if (rbuff) free(rbuff);
    if (wbuff) free(wbuff);
    return -error;
}
#endif


#ifdef EFUSE_LICENCE_ENABLE

static int
efuse_audio_license_decode(char *raw, unsigned char *license)
{
    int i;
    char * curr = raw;

    LOGE("efuse_audio_license_decode() raw=%s\n", raw);
    if (!curr)
        return -1;

    for (*license = 0, i = EFUSE_BYTES; i > 0; i--, curr++) {
        if (*curr == '1')
            *license |= 1 << (i - 1);
    }   
    
    LOGE("efuse_audio_license_decode() license=%x\n", *license);
    return 0;
}

/**
 * There are 4 bytes for licence,now we use byte 1--bit[1:0] for cntl 0-ac3,1-dts.
 */
int
efuse_write_audio_license(char *path, , RecoveryUI* ui)
{
    int fd;
    FILE *fp;
    unsigned char license = 0;
    char raw[32];

    ui->Print("Finding %s...\n", efuse_title[EFUSE_LICENCE]);
    fp = fopen_path(path, "r");
    if (fp == NULL) {
        LOGE("no %s found\n", efuse_title[EFUSE_LICENCE]);
        return -1;
    }

    ui->Print("Reading %s...\n", efuse_title[EFUSE_LICENCE]);
    fgets(raw, sizeof(raw), fp);
    if (strlen(raw) < EFUSE_BYTES) {
        LOGE("invalid %s\n", efuse_title[EFUSE_LICENCE]);
        check_and_fclose(fp, path);
        return -1;
    }

    check_and_fclose(fp, path);
    if (efuse_audio_license_decode(raw, &license)) {
        LOGE("invalid %s\n", efuse_title[EFUSE_LICENCE]);
        check_and_fclose(fp, path);
        return -1;
    }

    ui->Print("Writing %s...\n", efuse_title[EFUSE_LICENCE]);
    fd = efuse_opendev();
    if (fd < 0)
        return -1;

    if (lseek(fd, 0, SEEK_SET) == 0) {
        if (write(fd, &license, sizeof(license)) == 1) {
            if ((license & 0x3) > 0)
                ui->Print("Audio license enabled\n");
            else
                ui->Print("Audio license wrote\n");
        }
        else {
            LOGE("efuse write error\n");
            efuse_closedev(fd);
            return -1;
        }
    }

    efuse_closedev(fd);
    return 0;
}
#endif /*EFUSE_LICENCE_ENABLE */

/**
 *  Recovery efuse programming UI, current support efuse items:
 *  
 *    Audio license
 *    Ethernet MAC address
 *    Bluetooth MAC address
 */
int
recovery_efuse(int interactive, const char* args, Device * device)
{
    const char* menu[] = { "Choose an efuse item to program:",
                           "",
                           NULL };
    
    char prop[PROPERTY_VALUE_MAX];
    int result = 0;
    int chosen_item = 0;
    int efuse_item_index = 0;
    const char **headers = NULL;
    RecoveryUI * ui = device->GetUI();

    if (interactive < 0) {
        headers = prepend_title((const char**)menu);
        chosen_item = get_menu_selection(headers, (char **)efuse_items, 1, chosen_item, device);
        efuse_item_index = efuse_item_id[chosen_item];
    }
    else
        efuse_item_index = interactive;

    if (efuse_item_index > EFUSE_NONE && efuse_item_index < EFUSE_TYPE_MAX)
        ui->Print("\n-- Program %s...\n", efuse_title[efuse_item_index]);

    switch (efuse_item_index) {
        case EFUSE_VERSION:
             result = efuse_write_version((char *)args, ui);
             break;
#ifdef EFUSE_LICENCE_ENABLE
        case EFUSE_LICENCE:
            result = efuse_write_audio_license((char *)SDCARD_AUDIO_LICENSE, ui);
            break;
#endif /* EFUSE_LICENCE_ENABLE */
#ifdef SDCARD_EFUSE_MAC_ENABLE
        case EFUSE_MAC:
            result = efuse_write_mac((char *)SDCARD_ETHERNET_MAC, efuse_item_index, ui);
            break;
        case EFUSE_MAC_BT:
            result = efuse_write_mac((char *)SDCARD_BLUETOOTH_MAC, efuse_item_index, ui);
            break;
#endif 
    }

    if (efuse_item_index > EFUSE_NONE && efuse_item_index < EFUSE_TYPE_MAX) {
        if (result)
            ui->Print("Failed to write %s\n", efuse_title[efuse_item_index]);
        else
            ui->Print("\nWrite %s complete\n", efuse_title[efuse_item_index]);
    }

    if (headers) free(headers);
    return result;
}
